package de.ret_world.eet.encryption;

import de.ret_world.eet.code.CodeTable;
import de.ret_world.eet.code.Symbol;
import java.util.ArrayList;

/**
 * Used to decrypt encrypted data using a CodeTable and password
 * @author Emu
 */
public class Decrypt {

    private final CodeTable table;
    private final boolean removeSymbols;

    /**
     * Creates a new Decrypter.
     * @param table the CodeTable to decrypt the data
     * @param removeSymbols set this to "true" if you want to remove all Symbols not in the Alphabet of the CodeTable during the decryption process.
     */
    public Decrypt(CodeTable table, boolean removeSymbols) {
        this.table = table;
        this.removeSymbols = removeSymbols;
    }

    /**
     * Decrypts a given String with the given password using the internal CodeTable
     * @param password the password to decrypt the data
     * @param text the encrypted data
     * @return the decrypted data
     */
    public String decrypt(String password, String text) {
        ArrayList<Symbol> alph = new ArrayList<Symbol>(table.getAlphabet().getSymbols());
        StringBuilder decrypted = new StringBuilder();
        int i = 0;
        int l = alph.get(0).getLength();

        if (!table.getAlphabet().checkPassword(password)) {
            throw new IllegalArgumentException("Password contains symbols not in the alphabet!");
        }

        while (!text.isEmpty()) {
            Symbol chr = new Symbol(text.substring(0, l));
            Symbol pwd = new Symbol(password.substring(i, i + l));

            text = text.substring(l);

            int row = alph.indexOf(pwd);
            int col = table.getCol(row, chr);

            if (col >= 0 && row >= 0) {
                decrypted.append(alph.get(col));
                i += l;
                if (i >= password.length()) {
                    i = 0;
                }
            } else {
                if (!removeSymbols) {
                    decrypted.append(chr);
                }
            }
        }

        return decrypted.toString();
    }
}
